//  call apply 以及bind 用法

var people = {
    sex: '男'
}
// call 方法模拟
Function.prototype._call = function (context) {
    // 没有参数的话默认为window对象
    let object = context || window;
    // 为object添加一个属性，将调用_call方法的对象赋值给该属性func
    object.func = this;
    // 剔除传入的第一个参数
    let args = [...arguments].slice(1);
    // 将剩余参数传入object新增的方法func中调用
    let result = object.func(...args);
    // 删除刚刚添加的新属性
    delete object.func;
    // 返会结果
    return result
}

// apply 方法模拟

Function.prototype._apply = function (context) {
    let object = context || window;
    object.fn = this;
    let arg, result;
    if (arguments[1] && !Array.isArray(arguments[1])) {
        throw Error('第二个参数必须是数组！')
    } else {
        arg = arguments[1];
    }
    result = arg ? object.fn(...arg) : object.fn()
    delete object.fn
    return result

}

function consoleLog(name, age) {
    console.log(name)
    console.log(age)
    console.log(this.sex)
}

// consoleLog._call(people, '小米', '22')
// consoleLog._apply(people)

// new 的过程
// 1.新生成了一个对象
// 2.链接到原型
// 3.绑定 this
// 4.返回新对象

function New(){
    // 创建一个中间变量空对象
    let tempObj = {};
    let Con = arguments[0];
    // 将对象链接到原型链
    tempObj.__proto__ = Con.prototype;
    // 绑定this
    let result = Con._call(tempObj,arguments)
    // 返回新对象
    return typeof result === 'object' ? result : tempObj;
}
